<!--
 * @Author: long
 * @Date: 2021-09-15 10:33:52
 * @LastEditTime: 2021-10-27 17:11:00
 * @LastEditors: Please set LastEditors
 * @Description: 脸库详情
 * @FilePath: \ant-design-vue-jeecge:\hjimi\人脸辨识云\html\gitlab\pc\facecloudwebsite\src\views\face-recognition\faceLibrary-manage\faceList.vue
-->
<style lang="less">
.upload_face_img {
  top:0px!important;
  .ant-upload-list {
  margin-top: 20px;
  max-height: 500px;
  overflow-y: auto;
  & > div {
    width: 200px;
    float: left;
    margin-left: 10px;
  }
}
}
.face_attr_lineH {
  p {
    line-height: 12px;
  }
}
</style>
<template>
  <div class="app_container">
    <div class="box_style">
     <div class="flexbetween pb25"><span class="table_tit_txt">人脸列表</span> 
     <div><a-button type="primary" class="mr10" @click="onSearch">刷新</a-button><a-button v-permission="['root']" type="primary" @click="visible_uploadImg = true"><a-icon type="plus" /> 新增人脸</a-button></div>
     </div>
      <a-table
        :columns="columns"
        :scroll="{ y: 600 }"
        :dataSource="tableData"
        :loading="loading"
        :rowKey="(tableDatas) => tableDatas.id"
        :pagination="false"
      >
      <div slot="imageBase64" slot-scope="text, row"><div class="imgUrl"><i class="el-icon-loading" v-if="imgLoadIcon"></i><img width="100" :src="row.imageBase64"></div></div>
      <div slot="action" slot-scope="text, row">

       <a-popover placement="left">
        <template slot="content">
         <div class="face_attr_lineH">
           <a-spin :spinning="attr_spinning">
            <p>性别：{{ faceAttr.age }}</p>
            <p>年龄：{{ faceAttr.gender }}</p>
           <p>人脸框位置：{{ row.faceRect }}</p>
           </a-spin>
         </div>
        </template>
        <template slot="title"><span>人脸属性</span></template>
       <span class="theme_col pointer pr10" @mouseenter="getFaceAttr(row)">人脸属性</span> 
      </a-popover>
      
       <span class="theme_col pointer pr10" @click="downLoadImgHanle(row)">下载</span>
        <a-popconfirm placement="bottom" v-show="row.roleType !== 'default'" ok-text="删除" cancel-text="取消" @confirm="delfaceImage(row)">
        <template slot="title">
          <p>确认删除该人脸图片吗？</p>
        </template>
        <span class="pointer danger_col">删除</span>
      </a-popconfirm>
      </div>
      </a-table>
      
      <a-pagination
        right
        show-quick-jumper
        hideOnSinglePage
        showSizeChanger
        :default-current="pagingQuery['current']"
        :defaultPageSize="pagingQuery['size']"
        :total="pagingQuery['total']"
        :show-total="total => `共 ${total} 条`"
        :page-size-options="['20', '40', '60', '80', '90', '100']"
        @change="handleCurrentChange"
        @showSizeChange="handleSizeChange"
      />
     </div>

     <a-modal title="上传人脸图片" :visible="visible_uploadImg" width="50%" dialogClass="upload_face_img" @cancel="faceHideHandle" :maskClosable="false">
      <div>
         <a-upload-dragger
             :data="imgParams"
            :multiple="true"
            @preview="handlePreview"
             @change="handleChange"
            :auto-upload="true"
            :before-upload="imgBeforeHandle"
            :customRequest="httpRequest"
            list-type="picture"
            :fileList="fileList"
          >
            <p class="ant-upload-drag-icon">
              <a-icon type="inbox" />
            </p>
            <p class="ant-upload-text">点击或拖拽人脸照片到此区域进行上传</p>
            <p class="ant-upload-hint">上传图片（jpg/png/jpeg/bmp）小于3M，请上传无遮挡单人正面照，单次最多可上传50张</p>
          </a-upload-dragger>
           <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
      </div>
      <div slot="footer">
          <a-button @click="clearFileList">清空</a-button>
          <a-button @click="faceHideHandle">取消</a-button>
        </div>
       </a-modal>
  </div>
</template>
<script>
import { getLibraryimage, deleteFaceImage, faceUpload, faceAttribute, getFaceImage } from '@/api/face-recognition/faceLibraryManage'
import { DOWNFILE } from '@/utils'
let vm

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })
}

export default {
  data() {
    return {
      visible_uploadImg: false,
      imgLoadIcon: false,
      attr_spinning: true,

      previewVisible: false,
      previewImage: '',
      

      imgParams: { //  图片上传参数
          code: ''
      },

      faceAttr: {
        age: '',
        gender: ''
      },
      fileList: [],
      fileUploadState: '',
      columns: [
        {
          title: "序号",
          customRender: (text, record, index) =>
            `${(this.pagingQuery.current - 1) * this.pagingQuery.size + index + 1}`,
        },
        { title: "人脸图片", dataIndex: "imageBase64", scopedSlots: { customRender: 'imageBase64' } },
        { title: "人脸ID", dataIndex: "id", scopedSlots: { customRender: 'id' }},
        { title: "图像标志", dataIndex: "imageId" },
        { title: "图像格式", dataIndex: "imageType" },
        { title: "上传时间", dataIndex: "createTime" },
        { title: "操作", dataIndex: "action", width: 180, scopedSlots: { customRender: 'action' }}
      ],
      tableData: [],
      imageBase64: '',
      loading: true,
      pagingQuery: {
        libraryCode: '',
        current: 1,
        size: 20,
        total: 20,
      },
    }
  },
  watch: {
    $route() {
      let querys = this.$route.query
     if(!querys.id) {
       this.$router.go(-1)
     }
    }
  },
  methods: {

/**
 * @description: 人脸图上传
 */
//  截取图片名
    cutImageName(filename) {
      let fileReg = /\.{1}[a-z]{1,}$/
        if (fileReg.exec(filename) !== null) {
            return (filename.slice(0, fileReg.exec(filename).index))
        } else {
            return filename
        }
    },
    imgBeforeHandle(file, fileList) {
      this.imgParams.files = file
        let params = this.imgParams,
            readers = new FileReader(),
            fileName = this.cutImageName(file.name)
            this.imgParams.name = fileName
          
        function imageType () { return ['image/jpeg', 'image/jpg', 'image/png', 'image/bmp'].includes(file.type) }

        const isLt3M = file.size / 1024 / 1024 < 3
              if (!imageType()) { 
                this.$msg.error('上传人脸图片只能是四种格式（jpg/jpeg/png/bmp）!')
                } 
              else if (!isLt3M) {
                 this.$msg.error('上传人脸图片大小不能超过3MB!')
              } else { 
                  let format = file.type.substr(file.type.indexOf('/') + 1)

                   params['imageDescs[0].format'] = format.toUpperCase()
                    if(params['imageDescs[0].format'] === 'JPEG') {
                      params['imageDescs[0].format'] = 'JPG'
                      }
                         new Promise((reslove) => {
                           readers ? reslove() : String
                         }).then(() => {
                            readers.readAsDataURL(file)
                            readers.onload = function (e) {
                            let url = e.target.result,
                                img = new Image()
                                img.src = url
                            img.onload = function () { 
                                params.width = img.width
                                params.height = img.height
                            }
                        }
                         })
              }
            return imageType() && isLt3M
    },
    imgExceedHandle(files, fileList) {
        this.$message({
                      message: files.length > 50 ? '单次最多可上传50张': '上传总数不能超过50张，请先清空',
                       type: "warning"
                  })
       },
     async httpRequest(content){
         let formData = new FormData() 
          // formData.delete('file')
          formData.append('files', content.file) 
          formData.append('code', this.imgParams.code)

          let param = {
            "code": this.imgParams.code,
            "imageDescs": [{"format": this.imgParams['imageDescs[0].format']}]
          }

          formData.append("param", new Blob([JSON.stringify(param)], { type:"application/json" }))
          
           setTimeout(() => {
              formData.append('imageDescs.width', this.imgParams['width'])
              formData.append('imageDescs.height', this.imgParams['height'])

              faceUpload(formData).then((res) => {
                if(res) {
                  if(res.code == 10204) { // 超出目标库数量限制
                      this.clearFileList()
                    }else if(res.data[0].isSuccess) {
                  this.fileList[this.fileList.length - 1].status = 'done'
                    this.fileUploadState = 0
                        this.getTableList()
                     } else if(!res.data[0].isSuccess) {
                       
// 提示图片上传失败原因  
                       switch(res.data[0].errorCode) {
                         case 11001 : errTxtTip('模糊');break
                         case 11002 : errTxtTip('强光照');break
                         case 11003 : errTxtTip('弱光照');break
                         case 11004 : errTxtTip('口罩遮挡');break
                         case 11005 : errTxtTip('墨镜遮挡');break
                         case 11006 : errTxtTip('手遮挡');break
                         case 11007 : errTxtTip('其他遮挡');break
                         case 11008 : errTxtTip('张口');break
                         case 11009 : errTxtTip('闭眼');break
                         case 11010 : errTxtTip('多人脸');break
                         case 11011 : errTxtTip('无人脸');break
                         case 11013 : errTxtTip('人脸过小');break
                         case 10212 : errTxtTip('多人脸');break
                         default : this.$msg.warning(content.file.name + ' 上传失败！请另选上传')
                       }

                      function errTxtTip(txt) {
                          vm.fileUploadState = 1
                          vm.$msg.warning(content.file.name + `系统检测为: ${ txt }！上传失败！`)
                          // vm.clearFileList()
                      }
                       this.fileList[this.fileList.length - 1].status = 'error'
                       console.log(this.fileList.length - 1)
                     } else {
                      //  this.clearFileList()
                      this.fileList[this.fileList.length - 1].status = 'error'
                     }
                  }
                })
           }, 100)
            },
     async handleChange(info) {
       info.fileList.forEach((item, index) => {
         item.s = null
       })
       this.fileList = info.fileList
      //  info.fileList[info.fileList.length - 1].status = 'done'
      //  new Promise((resolve) => {
      //       let timer = setTimeout(() => {
      //         let state = this.fileUploadState
      //           if(state !== '') {
      //             resolve(state)
      //         }
      //       }, 2000)
      //     }).then((val) => {
      //       if(val === 0) {
      //         info.fileList[info.fileList.length - 1].status = 'done'
      //       } else {
      //         info.fileList[info.fileList.length - 1].status = 'error'
      //       }
      //     })
    },
  async handlePreview(file) {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj)
      }
      this.previewImage = file.url || file.preview
      this.previewVisible = true
    },
     clearFileList() {
        this.fileList = []
     },
  
   /**
    * @description: 人脸图列表
    */
   onSearch() {
      let params = this.pagingQuery
          params.current = 1
      this.getTableList()
    },
    getTableList() {
      this.loading = true
      let params = this.pagingQuery
      let { libraryCode } = this.pagingQuery
      
    getLibraryimage(params).then((res) => {
        if (res.code === 0) {
            this.tableData = []
             params.size = res.data.size
             params.total = res.data.total
             params.current = res.data.current
             let { records } = res.data
          
          if(records.length !== 0) {
            records.map((item, index) => {
              
                 getFaceImage(libraryCode, item.imageId).then((base64) => { // 获取单张人脸图片
                   if(base64.code === 0 && base64.data) {
                     this.tableData.push({
                       createTime: item.createTime,
                       id: item.id,
                       imageBase64: `data:png;base64,${base64.data}`,
                       imageId: item.imageId,  
                       imageType: item.imageType,
                       faceRect: item.faceRect
                     })
                   } else {
                     if(records.length === records[records.length - 1]) {
                       this.$msg.error('部分人脸图形获取失败！')
                     }
                   }
                   })
                 setTimeout(() => this.loading = false, 1000)
                 this.loading = false
       })
        } else {
          this.loading = false
          this.tableData = []
        }
        } else {
          this.$msg.error(res.msg)
          this.loading = false
        }
      }).catch(() => this.loading = false)
    },

// 获取人脸属性（年龄性别）
    getFaceAttr(row) {
        this.attr_spinning = true
        this.faceAttr.age = this.faceAttr.gender = ''
       faceAttribute( 
          {
          datas: 'age_gender',
          imageId: row.imageId,
          libraryCode: this.pagingQuery.libraryCode
          }).then((res) => {
           if(res.code === 0) {
             this.attr_spinning = false
             const { data } = res
             
             this.faceAttr.age = data.age
             this.faceAttr.gender = data.gender === 'male' ? '男' : '女'
          } else {
            this.$msg.error('人脸属性获取失败！')
        }
       })
    },
    handleSizeChange(current, size) {
      this.pagingQuery.size = size
      this.getTableList()
    },
    handleCurrentChange(page, pageSize) {
      this.pagingQuery.current = page
      this.getTableList()
    },
    delfaceImage(row) {
      let { libraryCode } = this.pagingQuery
      deleteFaceImage(libraryCode, row.imageId).then(res => {
        if(res.code === 0) {
         this.$msg.success(res.msg), this.getTableList()
        } else {
          this.$msg.error(res.msg)
        }
      })
  },
   downLoadImgHanle(row) {
   DOWNFILE.downloadIamge(row.imageBase64, row.imageId, false)
   },
   faceHideHandle() {
      this.visible_uploadImg = false
      this.clearFileList()
      },
    handleCancel() {
      this.previewVisible = false
    }
  },
  created() {
    vm = this
    let libraryCode = this.$route.query.libraryCode
    this.pagingQuery.libraryCode = libraryCode
    this.imgParams.code = libraryCode
    this.getTableList()
  },
  mounted() {
  }
}
</script>